#include <iostream>
#include <functional>
#include <memory>
#include <string>
#include "include/muduo/net/TcpServer.h"
#include "include/muduo/net/EventLoop.h"
#include "include/muduo/net/TcpConnection.h"

class EchoServer
{
public:
    EchoServer(int port)
        : _tcpServer(&_baseLoop, muduo::net::InetAddress("0.0.0.0", port), "EchoServer", muduo::net::TcpServer::kReusePort)
    {
        _tcpServer.setConnectionCallback(std::bind(&EchoServer::onConnection, this, std::placeholders::_1));
        _tcpServer.setMessageCallback(std::bind(&EchoServer::onMessage, this, 
            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }

    void start()
    {
        _tcpServer.start();
        _baseLoop.loop();
    }

    ~EchoServer()
    {}
private:
    void onConnection(const muduo::net::TcpConnectionPtr& conn) // 连接建立/断开时回调
    {
        if(conn->connected())
        {
            std::cout << "connection established..." << std::endl;
        }
        else
        {
            std::cout << "connection closed..." << std::endl;
        }
    }

    void onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buffer, muduo::Timestamp timestamp)
    {
        std::string req = buffer->retrieveAllAsString();
        std::string resp = handleRequest(req);
        conn->send(resp);
    }

    std::string handleRequest(std::string req)
    {
        return "echo> " + req;
    }
private:
    muduo::net::EventLoop _baseLoop;
    muduo::net::TcpServer _tcpServer;
};

int main()
{
    std::unique_ptr<EchoServer> echoServer = std::make_unique<EchoServer>(9090);
    echoServer->start();

    return 0;
}